package com.macro.mall.portal.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.macro.mall.common.constants.Constants;
import com.macro.mall.dto.*;
import com.macro.mall.mapper.BmsActivitiesApplicantSnapshotMapper;
import com.macro.mall.model.BmsActivitiesApplicantSnapshot;
import com.macro.mall.model.BmsActivitiesApplicantSnapshotExample;
import com.macro.mall.model.UmsMember;
import com.macro.mall.portal.service.ActivitiesBaseService;
import com.macro.mall.portal.util.MemberUtil;
import com.macro.mall.portal.util.MemberUtils;
import com.macro.mall.portal.util.UserUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@Service
public abstract class ActivitiesBaseServiceImpl implements ActivitiesBaseService {

    @Autowired
    private BmsActivitiesApplicantSnapshotMapper bmsActivitiesApplicantSnapshotMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ActivitiesRegistrationResult activitiesRegistration(ActivitiesRegistrationParam registrationParam) {
        UmsMember user = MemberUtils.getUser();
        registrationParam.setWxUser(user);
        // 查询快照表详情
        BmsActivitiesApplicantSnapshotParam snapshotParam = new BmsActivitiesApplicantSnapshotParam();
        snapshotParam.setActivitiesId(registrationParam.getActivitiesId());
        snapshotParam.setActivitiesType(registrationParam.getActivitiesType());
        BmsActivitiesApplicantSnapshotDetail activitiesApplicantDetail = getActivitiesApplicantDetail(snapshotParam, registrationParam.getApplicationTime(), user);

        /*
        * 快照表记录为空
        * */
        if (Objects.isNull(activitiesApplicantDetail)) {
            return ActivitiesRegistrationResult.buildResult(Constants.ActivitiesResultEnum.SNAPSHOT_NULL_ERROR);
        }

        // 校验基本信息是否正确
        Boolean checked = checkBaseInfo(registrationParam);
        if (!checked) {
            return ActivitiesRegistrationResult.buildResult(Constants.ActivitiesResultEnum.BASE_INFO_ERROR);
        }
        int registratyCount = 0;
        if (Objects.nonNull(activitiesApplicantDetail.getApplicantNum()) && activitiesApplicantDetail.getApplicantNum() > 0){
            // 查询票数是否充足
            registratyCount = this.getActivitiesRegistratyCount(registrationParam);
            int update = bmsActivitiesApplicantSnapshotMapper.updateActivitiesLockApplicant(activitiesApplicantDetail,registratyCount);
            if (update == 0) {
                return ActivitiesRegistrationResult.buildResult(Constants.ActivitiesResultEnum.TICKETS_REMAIN);
            }
        }

        if (Objects.nonNull(activitiesApplicantDetail.getCost()) && activitiesApplicantDetail.getCost().compareTo(BigDecimal.ZERO) > 0){

        }
        //添加报名人数
        int insertCount = insetApplicantList(registrationParam);
        if (insertCount == 0 || (activitiesApplicantDetail.getActivitiesType().equals("1") && Objects.nonNull(activitiesApplicantDetail.getApplicantNum()) && activitiesApplicantDetail.getApplicantNum() > 0 && insertCount != registratyCount)){
            throw new RuntimeException(Constants.ActivitiesResultEnum.APPLICANT_ERROR.getMessage());
        }
        return ActivitiesRegistrationResult.buildResult(Constants.ActivitiesResultEnum.APPLICANT_SUCCESS);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public ActivitiesRegistrationResult activitiesCancel(ActivitiesRegistrationParam registrationParam) {
        UmsMember user = MemberUtils.getUser();
        registrationParam.setWxUser(user);
        // 查询快照表详情
        BmsActivitiesApplicantSnapshotParam snapshotParam = new BmsActivitiesApplicantSnapshotParam();
        snapshotParam.setActivitiesId(registrationParam.getActivitiesId());
        snapshotParam.setActivitiesType(registrationParam.getActivitiesType());

        BmsActivitiesApplicantSnapshotExample example = new BmsActivitiesApplicantSnapshotExample();
        example.createCriteria().andIdEqualTo(Constants.ActivitiesTypeEnum.getActivitiesSnapshot(registrationParam.getActivitiesType(),registrationParam.getActivitiesId(),registrationParam.getApplicationTime()));
        List<BmsActivitiesApplicantSnapshot> bmsActivitiesApplicantSnapshots = bmsActivitiesApplicantSnapshotMapper.selectByExample(example);
        if (CollectionUtil.isEmpty(bmsActivitiesApplicantSnapshots)) {
            return ActivitiesRegistrationResult.buildResult(Constants.ActivitiesResultEnum.SNAPSHOT_NULL_ERROR);
        }
        BmsActivitiesApplicantSnapshotDetail activitiesApplicantDetail = new BmsActivitiesApplicantSnapshotDetail();
        BeanUtils.copyProperties(bmsActivitiesApplicantSnapshots.get(0), activitiesApplicantDetail);

        // 修改库存信息
        int registratyCount = 0;
        if (Objects.nonNull(activitiesApplicantDetail.getApplicantNum()) && activitiesApplicantDetail.getApplicantNum() > 0){
            // 查询票数是否充足
            registratyCount = this.getActivitiesHasRegistratyCount(registrationParam);
            int update = bmsActivitiesApplicantSnapshotMapper.resetActivitiesLockApplicant(activitiesApplicantDetail,registratyCount);
            if (update == 0) {
                return ActivitiesRegistrationResult.buildResult(Constants.ActivitiesResultEnum.RESET_TICKETS_ERROR);
            }
        }

        // 取消报名人数
        handleApplicantStatus(registrationParam,"3");
        return ActivitiesRegistrationResult.buildResult(Constants.ActivitiesResultEnum.RESET_APPLICANT_SUCCESS);
    }

    private BmsActivitiesApplicantSnapshotDetail getActivitiesApplicantDetail(BmsActivitiesApplicantSnapshotParam param, LocalDateTime applicationTime, UmsMember user){
        BmsActivitiesApplicantSnapshotExample example = new BmsActivitiesApplicantSnapshotExample();
        example.createCriteria().andActivitiesIdEqualTo(param.getActivitiesId()).andActivitiesTypeEqualTo(param.getActivitiesType());
        List<BmsActivitiesApplicantSnapshot> bmsActivitiesApplicantSnapshots = bmsActivitiesApplicantSnapshotMapper.selectByExample(example);

        BmsActivitiesApplicantSnapshotDetail detail = new BmsActivitiesApplicantSnapshotDetail();;
        if (CollectionUtil.isEmpty(bmsActivitiesApplicantSnapshots)) {
            ActivitiesRegistrationDetail activitiesDetail = getActivitiesDetail(param.getActivitiesId());
            detail.setId(Constants.ActivitiesTypeEnum.getActivitiesSnapshot(param.getActivitiesType(),param.getActivitiesId(),applicationTime));
            detail.setActivitiesId(param.getActivitiesId());
            detail.setActivitiesType(param.getActivitiesType());
            detail.setLockApplicantNum(0);
            detail.setIsDelete(0);
            detail.setCost(activitiesDetail.getCost());
            detail.setApplicantNum(activitiesDetail.getApplicantCount());
            detail.setVersion(0);
            detail.setIsDelete(0);
            detail.setCreateUser(user.getId());
            detail.setCreateTime(new Date());
            detail.setUpdateUser(user.getId());
            detail.setUpdateTime(new Date());
            int i = bmsActivitiesApplicantSnapshotMapper.insertSelective(detail);
            if (i == 0){
                return null;
            }
            return detail;
        }
        BeanUtils.copyProperties(bmsActivitiesApplicantSnapshots.get(0), detail);
        return detail;
    }


    /**
     * 检查基本信息
     */
    abstract Boolean checkBaseInfo(ActivitiesRegistrationParam registrationParam);
    /**
     * 确定活动报名人数
     */
    abstract int getActivitiesRegistratyCount(ActivitiesRegistrationParam registrationParam);

    /**
     * 获取已报名人数
     */
    abstract int getActivitiesHasRegistratyCount(ActivitiesRegistrationParam registrationParam);

    /**
     * 查询活动详情
     */
    abstract ActivitiesRegistrationDetail getActivitiesDetail(String activitiesId);

    /**
     * 添加报名人数
     */
    abstract int insetApplicantList(ActivitiesRegistrationParam registrationParam);

    /**
     * 修改报名人数装态
     */
    abstract int handleApplicantStatus(ActivitiesRegistrationParam registrationParam, String status);

}
